#ifndef TASK_H
#define TASK_H
/************************************************
  * 描述
  * File: task.h
  * Author: qijiangyong@mozihealthcare.cn
  * Date: 2025-08-13
  * Update:
  ***********************************************/
#include "common/asyc/head.h"
#include <common/export.h>
#include <QDebug>
#include <QObject>
#include <QRunnable>
#include <QThread>
#include <QVariant>
#include <memory>

using task_priority = thread_pool_data::taskPriority;

// 辅助/代理类
class CXI_COMMON_EXPORT TaskProxy : public QObject
{
    Q_OBJECT
public:
    TaskProxy(int id, QObject* parent = nullptr) : QObject(parent), m_id(id) {}
    ~TaskProxy() { qDebug() << "task proxy destory."; }

signals:
    void taskFinished(int, const QVariant&);
    void taskError(int, const QString&);

public slots:
    void emitTaskFinished(const QVariant& result)
    {
        emit taskFinished(m_id, result);
    }
    void emitTaskError(const QString& err)
    {
        emit taskError(m_id, err);
    }

private:
    int m_id;
};

// 任务基类
class CXI_COMMON_EXPORT TaskBase : public QRunnable
{
public:
    TaskBase(int id, task_priority p)
        : m_id(id)
        , m_priority(p)
        , m_parent(std::make_unique<TaskProxy>(id))
    {
        setAutoDelete(true);
        QThread::currentThread()->setPriority(thread_pool_data::tp2qp(p));
    }
    virtual ~TaskBase() = default;

    int id() const { return m_id; }
    task_priority priority() const { return m_priority; }
    TaskProxy* proxy() { return m_parent.get(); }

protected:
    int m_id;   // id
    task_priority m_priority; // 优先级
    std::unique_ptr<TaskProxy> m_parent; // 父类对象[辅助类]
};
using runnable_t = TaskBase;
// 定义一个比较器，用于 std::priority_queue
// 目标：让任务优先级高的（priority 数值大）排在前面
struct compareTask {
    bool operator()(const runnable_t* a, const runnable_t* b) {
        // 返回 true 表示 a 的优先级低于 b，所以 b 应该排在 a 前面（更靠近堆顶）
        // 优先级低 = priority 数值小
        return a->priority() < b->priority();
        // 如果 a->priority=1 (LOW), b->priority=4 (EMERGENCY)
        // 1 < 4 -> true -> a < b -> a 优先级低于 b -> b (EMERGENCY) 应该在堆顶 -> 正确！
    }
};

// 任务类
template <class Func>
class Task : public TaskBase
{
public:
    Task(Func f, int id, task_priority priority = task_priority::TP_NORMAL)
        : TaskBase(id, priority)
        , m_func(std::move(f))
    {
        qDebug() << "task constructor..";
        qDebug() << QString("[p%1]inner priority:%2")
                    .arg(id).arg(QThread::currentThread()->priority());
    }
    ~Task()
    {
        qDebug() << "task destructor.";
    }

    // 执行函数
    void run() override
    {
        qDebug() << "task thread id:" << QThread::currentThreadId();
        qDebug() << QString("task %1 is running..").arg(m_id);
        if (!QThread::currentThread()->isInterruptionRequested()) {
            try {
                if constexpr (std::is_same_v<std::invoke_result_t<Func>, QVariant>) {
                    qDebug() << "[qv]this->" << this;
                    auto result = m_func();
                    QMetaObject::invokeMethod(proxy(),
                                              "emitTaskFinished",
                                              Qt::QueuedConnection,
                                              Q_ARG(QVariant, result)
                                              );
                } else {
                    qDebug() << "[v]this->" << this;
                    m_func();
                    QMetaObject::invokeMethod(proxy(),
                                              "emitTaskFinished",
                                              Qt::QueuedConnection,
                                              Q_ARG(QVariant, QVariant{})
                                              );
                }

            } catch (const std::exception& e) {
                qCritical() << "task failed:" << e.what();
                QMetaObject::invokeMethod(proxy(),
                                          "emitTaskError",
                                          Qt::QueuedConnection,
                                          Q_ARG(QString, QString::fromUtf8(e.what()))
                                          );
            }
        }
        else
        {
            qDebug() << "task cancelled.";
        }
    }

private:
    Func m_func; // 执行函数
};

#endif // TASK_H
